package com.moxie.ocr.ocr.utils;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;



public class MXImageUtils {
    /**
     * @return 矫正并裁剪好的身份证图片
     */
    public static Bitmap getBitmap(int[] imageData, int bitmapWidth, int bitmapHeight) {
        Bitmap image = null;
        if (imageData != null) {
            image = Bitmap.createBitmap(imageData, bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);
        }
        return image;
    }

    private static byte[] sRotateResult = null;

    public static byte[] rotateYUV420Degree90(byte[] data, int imageWidth, int imageHeight) {

        byte[] yuv = getStaticRotateResult(imageWidth, imageHeight);
        // Rotate the Y luma
        int i = 0;
        for (int x = 0; x < imageWidth; x++) {
            for (int y = imageHeight - 1; y >= 0; y--) {
                yuv[i] = data[y * imageWidth + x];
                i++;
            }

        }
        // Rotate the U and V color components
        i = imageWidth * imageHeight * 3 / 2 - 1;
        for (int x = imageWidth - 1; x > 0; x = x - 2) {
            for (int y = 0; y < imageHeight / 2; y++) {
                yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x];
                i--;
                yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + (x - 1)];
                i--;
            }
        }
        return yuv;
    }

    public static byte[] rotateYUV420Degree180(byte[] data, int imageWidth, int imageHeight) {
        byte[] yuv = getStaticRotateResult(imageWidth, imageHeight);
        int i = 0;
        int count = 0;

        for (i = imageWidth * imageHeight - 1; i >= 0; i--) {
            yuv[count] = data[i];
            count++;
        }

        i = imageWidth * imageHeight * 3 / 2 - 1;
        for (i = imageWidth * imageHeight * 3 / 2 - 1; i >= imageWidth
                * imageHeight; i -= 2) {
            yuv[count++] = data[i - 1];
            yuv[count++] = data[i];
        }
        return yuv;
    }

    public static byte[] rotateYUV420Degree270(byte[] data, int imageWidth, int imageHeight) {
        byte[] yuv = getStaticRotateResult(imageWidth, imageHeight);
        // Rotate the Y luma
        int i = 0;
        for (int x = imageWidth - 1; x >= 0; x--) {
            for (int y = 0; y < imageHeight; y++) {
                yuv[i] = data[y * imageWidth + x];
                i++;
            }
        }// Rotate the U and V color components
        i = imageWidth * imageHeight;
        for (int x = imageWidth - 1; x > 0; x = x - 2) {
            for (int y = 0; y < imageHeight / 2; y++) {
                yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + (x - 1)];
                i++;
                yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x];
                i++;
            }
        }
        return yuv;
    }

    private static byte[] getStaticRotateResult(int width, int height) {
        if (sRotateResult == null || sRotateResult.length != width * height * 3) {
            sRotateResult = new byte[width * height * 3 ];
        }
        return sRotateResult;
    }

    public static byte[] cropYUV420(byte[] data, int imageW, int imageH, int newImageH) {
        int cropH;
        int i, j, count, tmp;
        byte[] yuv = new byte[imageW * newImageH * 3 / 2];

        cropH = (imageH - newImageH) / 2;

        count = 0;
        for (j = cropH; j < cropH + newImageH; j++) {
            for (i = 0; i < imageW; i++) {
                yuv[count++] = data[j * imageW + i];
            }
        }

        //Cr Cb
        tmp = imageH + cropH / 2;
        for (j = tmp; j < tmp + newImageH / 2; j++) {
            for (i = 0; i < imageW; i++) {
                yuv[count++] = data[j * imageW + i];
            }
        }

        return yuv;
    }

    /**
     * 得到图片字节流 数组大小
     * */
    public static byte[] image2ByteArray(InputStream inStream) {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = -1;
        try {
            while((len = inStream.read(buffer)) != -1){
                outStream.write(buffer, 0, len);
            }

            outStream.close();
            inStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return outStream.toByteArray();
    }

    public static byte[] compressImageToNv21(Bitmap bitmap) {
        byte[] result = null;

        result = getNV21(bitmap.getWidth(), bitmap.getHeight(), bitmap);
        return result;
    }

    public static byte[] getNV21(int inputWidth, int inputHeight, Bitmap scaled) {

        int[] argb = new int[inputWidth * inputHeight];

        scaled.getPixels(argb, 0, inputWidth, 0, 0, inputWidth, inputHeight);

        byte[] yuv = new byte[inputWidth * inputHeight * 3];
        encodeYUV420SP(yuv, argb, inputWidth, inputHeight);

        scaled.recycle();

        return yuv;
    }

    public static void encodeYUV420SP(byte[] yuv420sp, int[] argb, int width, int height) {
        final int frameSize = width * height;

        int yIndex = 0;
        int uvIndex = frameSize;

        int a, R, G, B, Y, U, V;
        int index = 0;
        for (int j = 0; j < height; j++) {
            for (int i = 0; i < width; i++) {

                a = (argb[index] & 0xff000000) >> 24; // a is not used obviously
                R = (argb[index] & 0xff0000) >> 16;
                G = (argb[index] & 0xff00) >> 8;
                B = (argb[index] & 0xff) >> 0;

                // well known RGB to YUV algorithm
                Y = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16;
                U = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
                V = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128;

                // NV21 has a plane of Y and interleaved planes of VU each sampled by a factor of 2
                //    meaning for every 4 Y pixels there are 1 V and 1 U.  Note the sampling is every other
                //    pixel AND every other scanline.
                yuv420sp[yIndex++] = (byte) ((Y < 0) ? 0 : ((Y > 255) ? 255 : Y));
                if (j % 2 == 0 && index % 2 == 0) {
                    yuv420sp[uvIndex++] = (byte) ((V < 0) ? 0 : ((V > 255) ? 255 : V));
                    yuv420sp[uvIndex++] = (byte) ((U < 0) ? 0 : ((U > 255) ? 255 : U));
                }

                index++;
            }
        }
    }

    public static Bitmap copyBitmap(Bitmap srcBmp) {
        Bitmap desBmp = Bitmap.createBitmap(srcBmp.getWidth(), srcBmp.getHeight(),srcBmp.getConfig());
        Canvas canvas = new Canvas(desBmp);
        Paint paint = new Paint();
        paint.setColor(Color.BLACK);
        Matrix m = new Matrix();
        canvas.drawBitmap(srcBmp, m, paint);
        return desBmp;
    }
}
